package crawler.model;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import business.service.MongoDbFactory;
import crawler.common.PostData;
import com.google.common.base.Joiner;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;

/**
 *
 * @author ngotandieu
 */
public class BongDaModel {

    private static final String BONGDA_COLLECTION = "post";
    private static final Logger logger = Logger.getLogger(BongDaModel.class);
    private static final Lock createLock_ = new ReentrantLock();
    private static BongDaModel _instance = null;

    public static BongDaModel getInstance() {
        if (_instance == null) {
            createLock_.lock();
            try {
                if (_instance == null) {
                    _instance = new BongDaModel();

                }
            } finally {
                createLock_.unlock();
            }
        }
        return _instance;
    }

    public BongDaModel() {
        try {
        } catch (Exception ex) {
            logger.error("BongDaModel: " + ex);
        }
    }

    public List<PostData> getPost(int start, int limit) {
        List<PostData> lstPost = new LinkedList<>();
        try {
            BasicDBObject basicDBObject = new BasicDBObject("published", -1);
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);
            DBCursor cursor = coll.find().sort(basicDBObject);

            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }

            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                lstPost.add(fromDB(dbObject));
            }
        } catch (Exception ex) {
            logger.error("BongDaModel.getPost: " + ex.getMessage(), ex);
        }
        return lstPost;
    }

    public PostData getPostById(String id) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject("_id", new ObjectId(id));
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);
            DBCursor cursor = coll.find(basicDBObject);
            if (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                PostData postData = fromDB(dbObject);
                return postData;
            }
        } catch (Exception ex) {
            logger.error("BongDaModel.getPostById: " + ex.getMessage(), ex);
        }
        return null;
    }

    public static PostData fromDB(DBObject dbObject) {
        String objectId = ((ObjectId) dbObject.get("_id")).toString();
        String site = (String) dbObject.get("site");
        String categoryCode = (String) dbObject.get("categoryCode");
        String category = (String) dbObject.get("category");
        String title = (String) dbObject.get("title");
        String thumb = (String) dbObject.get("thumb");
        String thumbFb = (String) dbObject.get("thumbFb");
        String url = (String) dbObject.get("url");
        String desc = (String) dbObject.get("desc");
        String content = (String) dbObject.get("content");
        String strImages = (String) dbObject.get("images");
        List<String> lstImages = null;
        if (strImages != null && !strImages.isEmpty()) {
            lstImages = Arrays.asList(strImages.split(","));
        }
        String tags = (String) dbObject.get("tags");
        String author = (String) dbObject.get("author");
        long created = (long) dbObject.get("created");
        long published = (long) dbObject.get("published");
        String urlFb = (String) dbObject.get("urlFb");
        String titleFb = (String) dbObject.get("titleFb");
        String descFb = (String) dbObject.get("descFb");
        String siteFb = (String) dbObject.get("siteFb");
        PostData postData = new PostData(site,null, category, objectId, title, thumb, thumbFb, url, desc, content, lstImages, tags, author, published, created, urlFb, titleFb, descFb, siteFb);
        return postData;
    }

    public long getPostCount(String pid) {
        long count = 0;
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);
            count = coll.getCount();
        } catch (Exception ex) {
            logger.error("BongDaModel.getPostCount: " + ex.getMessage(), ex);
        }
        return count;
    }

    public boolean deletePost(String id) {
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);
            coll.remove(new BasicDBObject("_id", new ObjectId(id)));

            return true;
        } catch (Exception ex) {
            logger.error("BongDaModel.deletePost: " + ex.getMessage(), ex);
        }
        return false;
    }

    public String addNewPost(PostData postData) {
        String id = "";
        DB db = null;
        DBCollection coll;
        try {
            BasicDBObject basicDBObject = generateObject(postData);

            db = MongoDbFactory.getConnection();
            coll = db.getCollection(BONGDA_COLLECTION);
            coll.insert(basicDBObject);

            ObjectId objectId = (ObjectId) basicDBObject.get("_id");
            id = objectId.toString();
        } catch (Exception ex) {
            logger.error("BongDaModel.addPost: " + ex.getMessage(), ex);
        }
        return id;
    }

    public boolean updatePost(PostData postData) {
        try {
            BasicDBObject basicDBObject = generateObject(postData);

            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);

            BasicDBObject updateDBObject = new BasicDBObject("$set", basicDBObject);
            BasicDBObject searchDBQuery = new BasicDBObject("_id", new ObjectId(postData.getId()));
            coll.update(searchDBQuery, updateDBObject);
            return true;
        } catch (Exception ex) {
            logger.error("BongDaModel.updatePost: " + ex.getMessage());
        }
        return false;
    }

    public List<PostData> getRelatedPost(String pid, String id, int start, int limit) {
        List<PostData> lstPost = null;
        try {
            BasicDBObject basicDBObject = new BasicDBObject("time", -1);
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);

            BasicDBObject queryDBObject = new BasicDBObject("pid", pid);
            if (!id.equalsIgnoreCase("")) {
                ObjectId objectId = new ObjectId(id);
                int timestamp = objectId.getTimestamp();
                queryDBObject.append("created", new BasicDBObject("$gt", timestamp));
            }
            DBCursor cursor = coll.find(queryDBObject).sort(basicDBObject);

            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }

            lstPost = new ArrayList<>();
            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                lstPost.add(fromDB(dbObject));
            }
        } catch (Exception ex) {
            logger.error("BongDaModel.getRelatedPost: " + ex.getMessage(), ex);
        }
        return lstPost;
    }

    public boolean checkPostExists(String link) {
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(BONGDA_COLLECTION);
            BasicDBObject queryDBObject = new BasicDBObject("url", link);
            DBCursor cursor = coll.find(queryDBObject);

            if (cursor.hasNext()) {
                return true;
            }
        } catch (Exception ex) {
            logger.error("PostModel.checkPostExists: " + ex.getMessage(), ex);
        }
        return false;
    }

    private BasicDBObject generateObject(PostData postData) {
        BasicDBObject basicDBObject = new BasicDBObject()
                .append("site", postData.getSite())
                .append("category", postData.getCategory())
                .append("title", postData.getTitle())
                .append("thumb", postData.getThumb())
                .append("url", postData.getUrl())
                .append("desc", postData.getDesc())
                .append("content", postData.getContent())
                .append("images", Joiner.on(",").join(postData.getImages()))
                .append("tags", postData.getTags())
                .append("published", postData.getPublished())
                .append("author", postData.getJournalist())
                .append("created", postData.getCreated())
                .append("thumbFb", postData.getThumbFb())
                .append("urlFb", postData.getUrlFb())
                .append("titleFb", postData.getTitleFb())
                .append("descFb", postData.getDescFb())
                .append("siteFb", postData.getSiteFb());
        return basicDBObject;
    }
}
